package com.bj58.ecdata.dashboard.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 
 * 时间日期工具类
 * 
 * <p>
 * detailed comment
 * 
 * @author guolu 2015-1-24
 * @see
 * @since 1.0
 */
public class DDateUtils {

	private static Log log = LogFactory.getLog(DDateUtils.class);
	
	 /** 存放不同的日期模板格式的sdf的Map */
    private static Map<String, ThreadLocal<SimpleDateFormat>> sdfMap = new ConcurrentHashMap<String, ThreadLocal<SimpleDateFormat>>();

    /* 
     * 返回一个ThreadLocal的sdf,每个线程只会new一次sdf
     * @param pattern
     * @return
    */
   @SuppressWarnings("unused")
   private static SimpleDateFormat getSdf(final String pattern) {
//	   DateFormatUtils.format(date, pattern);
//	   org.apache.commons.lang3.time.DateUtils.
       ThreadLocal<SimpleDateFormat> tl = sdfMap.get(pattern);
       // 此处的双重判断和同步是为了防止sdfMap这个单例被多次put重复的sdf
       if (tl == null) {
           synchronized (sdfMap) {
               tl = sdfMap.get(pattern);
               if (tl == null) {
                   // 只有Map中还没有这个pattern的sdf才会生成新的sdf并放入map
                   // 这里是关键,使用ThreadLocal<SimpleDateFormat>替代直接new SimpleDateFormat
                   tl = new ThreadLocal<SimpleDateFormat>() {
                       @Override
                       protected SimpleDateFormat initialValue() {
//                           System.out.println("thread: " + Thread.currentThread() + " init pattern: " + pattern);
                           return new SimpleDateFormat(pattern);
                       }
                   };
                   sdfMap.put(pattern, tl);
               }
           }
       }

       return tl.get();
   }
    
	/**
	 * 字符串转为Date
	 * @param strDate
	 * @return
	 */
	public static Date strToDate(String strDate, String pattern) {
		try {
			return org.apache.commons.lang3.time.DateUtils.parseDate(strDate, pattern);
		} catch (ParseException e) {
			log.error("", e);
		}
		return null;
	}
	
	/**
	 * 日期对象转字符串
	 */
	public static String dateToStr(Date date, String pattern) {
		try {
			return DateFormatUtils.format(date, pattern);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 输入日期，返回之前i月的月份
	 * @param date
	 * @param pattern
	 * @return
	 */
	public static String varDate(String date, String pattern,int field, int amount) {
		try {
			Date d = strToDate(date,pattern);
		    Calendar now = Calendar.getInstance();  
		    now.setTime(d);
		    now.add(field, amount);
			return dateToStr(now.getTime(),pattern);
		} catch (Exception pe) {
			pe.printStackTrace();
		}
		return null;
	}

	
	/**
	 * 时间跨度
	 * 
	 * @param begin
	 * @param end
	 * @return
	 * @author guolu 2015-1-24
	 */
	public static List<String> getDays(String begin, String end) {
		Date beginDate = null;
		Date endDate = null;
		beginDate = strToDate(begin, "yyyyMMdd");
		endDate = strToDate(end, "yyyyMMdd");
		if (beginDate == null || endDate == null) {
			return Collections.emptyList();
		}

		Calendar c = Calendar.getInstance();
		c.setTime(beginDate);
		List<String> result = new ArrayList<String>();
		while (c.getTime().before(endDate)) {
			result.add(dateToStr(c.getTime(),"yyyyMMdd"));
			c.add(Calendar.DATE, 1);
		}

		return result;
	}

	public static String formatDay(Date date) {
//		log.error(date);
		String day = dateToStr(date,"yyyyMMdd");
		return day;
	}

	/**
	 * 按时间查询的起始时间-日
	 * 
	 * @return
	 * @author guolu 2015-1-26
	 */
	public static String getBeginDay() {
		return "20140101";
	}

	/**
	 * 按时间查询的结束时间-日
	 * 
	 * @return
	 * @author guolu 2015-1-26
	 */
	public static String getEndDay() {
		return formatDay(getYesterday());
	}

	/**
	 * 昨日时间
	 * 
	 * @return
	 * @author guolu 2015-1-26
	 */
	public static Date getYesterday() {
		Calendar c = Calendar.getInstance();
		c.add(Calendar.DATE, -1);
		return DateUtils.truncate(c, Calendar.DATE).getTime();
	}

	/**
	 * 
	 * @param date
	 * @return
	 * @author guolu 2015-1-26
	 */
	public static Date getLastDay(Date date) {
		return DateUtils.addDays(date, -1);
	}

	/**
	 * 返回某日的上周--定义为减去8天
	 * 
	 * @param date
	 * @return
	 * @author guolu 2015-1-26
	 */
	public static Date getLastWeek(Date date) {
		return DateUtils.addDays(date, -7);
	}

	/**
	 * 返回某日的上个月--定义为减去31天
	 * 
	 * @param date
	 * @return
	 * @author guolu 2015-1-26
	 */
	public static Date getLastMonth(Date date) {
		return DateUtils.addDays(date, -31);
	}

	public static String getLastDay(String date) {
			return varDate(date, "yyyyMMdd", Calendar.DATE, -1);
	}

	public static Date parseDate(String date) {
		return strToDate(date, "yyyyMMdd");
	}
	
	

	public static long getTruncatedMinute() {
		return DateUtils.truncate(new Date(), Calendar.MINUTE).getTime();
	}

	public static long getTruncatedHour() {
		return DateUtils.truncate(new Date(), Calendar.HOUR).getTime();
	}

	public static long getTruncatedToday() {
		return DateUtils.truncate(new Date(), Calendar.DATE).getTime();
	}

	public static long truncateToMinute(long time) {
		return DateUtils.truncate(new Date(time), Calendar.MINUTE).getTime();
	}

	public static long truncateToHour(long time) {
		return DateUtils.truncate(new Date(time), Calendar.HOUR).getTime();
	}

	public static long truncateToToday(long time) {
		return DateUtils.truncate(new Date(time), Calendar.DATE).getTime();
	}

}
